package top.superflow.utils

import java.util.Properties

import top.superflow.constant.GlobalConst
import top.superflow.exception.ServerException
import scala.collection.JavaConverters._

object SuperflowENVUtil {
  private var SUPER_FLOW_HOME : String= System.getProperty("user.home") + "/.superflow"
  def init = synchronized  {
    initHome
    initConfig
    initDBHome
    initDBConfig
  }

  private def initHome = {
    val sysProps = System.getProperties()
    val customSuperflowHome : Any = sysProps.get(GlobalConst.SYSTEM_ENV_VAR_HOME)

    //set default super flow home
    if (customSuperflowHome == null) {
      System.setProperty(GlobalConst.SYSTEM_ENV_VAR_HOME, SUPER_FLOW_HOME)
    }else{
      SUPER_FLOW_HOME  = customSuperflowHome.toString
    }
  }

  def getHome = SUPER_FLOW_HOME

  private def initConfig = {
    val defaultConfig = PropertyUtil.getProp(GlobalConst.SYSTEM_CONFIG_URI)
    setEnvVar(defaultConfig)
    val customConfig = PropertyUtil.getProp(getCustomConfigFilePath)
    setEnvVar(customConfig)
  }

  private def getCustomConfigFilePath : String = {
    System.getProperty(GlobalConst.SYSTEM_ENV_VAR_HOME) + "/" + GlobalConst.SYSTEM_CONFIG_FILE
  }

  private def initDBConfig = {
    val defaultDBConfig = PropertyUtil.getProp(GlobalConst.SYSTEM_DB_CONFIG_FILE_URI)
    setEnvVar(defaultDBConfig)

    val customDBConfig = PropertyUtil.getProp(getCustomDBConfigFilePath)
    setEnvVar(customDBConfig)

    val dbProperties = PropertyUtil.getProp(GlobalConst.SYSTEM_DB_PROPERTY_FILE)
    setEnvVar(dbProperties)
  }

  private def getCustomDBConfigFilePath : String = {
    System.getProperty(GlobalConst.SYSTEM_ENV_VAR_HOME) + "/" + GlobalConst.SYSTEM_DB_CONFIG_FILE_KEY
  }

  private def initDBHome = {
    val sysProps = System.getProperties()
    val superFlowDBHome : Any = sysProps.get(GlobalConst.SYSTEM_ENV_VAR_DB_HOME)

    //set default super flow home
    if (superFlowDBHome == null) {
      val defaultSuperflowDBHome = getUserHome() + "/.superflow/database"
      System.setProperty(GlobalConst.SYSTEM_ENV_VAR_DB_HOME, defaultSuperflowDBHome)
    }
  }


  private def getUserHome() : String = {
    val sysProps = System.getProperties()
    sysProps.get("user.home").toString
  }

  private def setEnvVar(config : Option[Properties]) = {
    config match {
      case s if s.isEmpty =>
      case s if !s.isEmpty => {
        for ((k,v) <- s.get.asScala) {
          System.setProperty(k, v)
        }
      }
    }
  }

  def getAssuredProperty (key : String) : String = synchronized {
    var value = System.getProperty(key)
    if(value == null && GlobalConst.MUST_INITIALIZED_SYSTEM_VARS.contains(key)){
      init
      value = System.getProperty(key)

      if(value == null) throw new ServerException("Please make sure " + key + " is configured in the superflow.properties or superflow.db.properties")
    }
    value
  }

  def getProperty (key : String) : String = synchronized {
    System.getProperty(key)
  }

  def main(args: Array[String]): Unit = {
    init
    for ((k,v) <- System.getProperties.asScala)
      println(s"key: $k, value: $v")
  }

}
